package com.jiao.table.csql;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.jiao.comm.exception.CacheSysException;
import com.jiao.comm.exception.ReaderCacheInfoException;
import com.jiao.syntax.AbstractCsplExpressionParse;
import com.jiao.syntax.CsplExpressionParser;
import com.jiao.syntax.entity.CselTemplate;
import com.jiao.syntax.enums.TokenKind;
import com.jiao.syntax.impl.Expression;
import com.jiao.table.config.CacheDataLoad;
import com.jiao.table.entity.TableInfo;
import lombok.Getter;

import java.util.Collections;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * @Description
 * @Author Vincent.jiao
 * @Date 2022/5/19 17:22
 */
public abstract class ExpressionAbstract implements Expression  {
    protected String sourceValue;
    protected String tableName;
    protected TableInfo tableInfo;
    protected List<String> colunms;
    protected AbstractCsplExpressionParse parse;

    protected Map<String, Object> params = null;
    List<CselTemplate> cselTemplates;

    public ExpressionAbstract(AbstractCsplExpressionParse parse) {
        Class classObj = CacheDataLoad.getTableEntityClass(parse.getTableName());
        if(classObj == null){
            throw  new CacheSysException("此表没有对应的映射信息");
        }

        this.sourceValue = parse.getExpression();
        this.tableName = parse.getTableName();
        this.colunms = parse.getColunmNameList();
        this.tableInfo = CacheDataLoad.getTableInfo(classObj);
        this.parse = parse;
    }

    @Override
    public String getExpressionString() {
        return sourceValue;
    }

    @Override
    public String getExpressionTableName() {
        return tableName;
    }

    public <T> List<T> getTemplateValueList(CselTemplate template){
        if(template == null) {
            return null;
        }

        List data = new LinkedList();
        boolean isPrecompile = false;
        int idx = 0;
        for (CselTemplate item : cselTemplates) {
            //找倒当前的 template
            if(item.equals(template)) {
                if(TokenKind.PRECOMPILE.equals(item.getValueType())) {
                    for (int i = 0; i < item.getValues().size(); i++) {
                        data.add(getParam(String.valueOf(idx++)));
                    }

                } else if(TokenKind.PLACEHOLDER_35.equals(template.getValueType())) {
                    for(Object key : item.getValues()) {
                        data.add(getParam(getPlaceSymbolName(key.toString())));
                    }
                }

                isPrecompile = true;
                break;
            }

            if(TokenKind.PRECOMPILE.equals(item.getValueType())) {
                idx +=  item.getValues().size();        //下推 ? 的索引
            }
        }

        if(!isPrecompile) {
            data = template.getValues();
        }







//        for (Object item : template.getValues()){
//            if(TokenKind.PRECOMPILE.equals(template.getValueType())) {
//
//                //TODO 重写获取索引这里
//
//                for (CselTemplate item : cselTemplates) {
//                    if(item.getValueType().equals(TokenKind.PRECOMPILE)) {
//
//                    }
//                }
//
//                for (int i = 0; i < cselTemplates.size(); i++) {
//                    if(cselTemplates.get(i).getValueType().equals(TokenKind.PRECOMPILE)) {
//                        if(cselTemplates.get(i).equals(template)) {
//                            for (int j = 0; j < template.getValues().size(); j++) {
//
//                            }
//
//                            data.add(getParam(String.valueOf(idx + template.getValues().size())));
//                            break;
//                        } else {
//                            idx += cselTemplates.get(i).getValues().size();
//                        }
//                    }
//                }
//
//                isPrecompile = true;
//
//            } else if(TokenKind.PLACEHOLDER_35.equals(template.getValueType())) {
//                data.add(getPlaceSymbolName(item.toString()));
//                isPrecompile = true;
//            }
//        }
//
//        if(!isPrecompile) {
//            data = template.getValues();
//        }

        return data;
    }

    public <T> T getTemplateValue(CselTemplate template){
        List list = getTemplateValueList(template);
        return CollectionUtil.isEmpty(list) ? null : (T) list.get(0);
    }

    /**
     * 根据占位符返回占位符名.
     * 例如：#{username} 返回 username
     * @param symbol
     * @return
     */
    protected String getPlaceSymbolName(String symbol) {
        if(StrUtil.isEmpty(symbol)) {
            return "";
        }

        int start = symbol.indexOf('{');
        int end = symbol.indexOf('}');

        if(start != -1 &&  end != -1) {
            return symbol.substring(start + 1, end);
        } else if (start != -1) {
            return symbol.substring(start + 1);
        } else {
            return symbol.substring(0, end);
        }
    }

    protected <T> T getParam(String key) {
        if(StrUtil.isEmpty(key)) {
            return null;
        }

        Object val = params.get(key);

        if(val == null) {
            throw new ReaderCacheInfoException("找不到表达式:" + sourceValue + " 中预编译的参数" + key);
        }

        T t = null;
        if(Long.class.equals(val.getClass()) || long.class.equals(val.getClass())) {
            t = (T) Long.valueOf(val.toString());
        } else if(Integer.class.equals(val.getClass()) || int.class.equals(val.getClass())) {
            t = (T) Integer.valueOf(val.toString());
        } else if(String.class.equals(val.getClass())) {
            t = (T) val.toString();
        } else if(Date.class.equals(val.getClass())) {
            t = (T) new Long(((Date)val).getTime());
        }

        return t;
    }
}
